{
  "nbformat": 4,
  "nbformat_minor": 0,
  "metadata": {
    "colab": {
      "name": "AutoTrace1.03.08.ipynb",
      "provenance": [],
      "collapsed_sections": [],
      "toc_visible": true
    },
    "kernelspec": {
      "name": "python3",
      "display_name": "Python 3"
    },
    "accelerator": "GPU"
  },
  "cells": [
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "rG0sn1m3y-BJ"
      },
      "source": [
        "# colab版MMD自動トレースへようこそ！(実行編)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "oqgb3dm4Meeb"
      },
      "source": [
        "# 始めに\n",
        "\n",
        "このツールの稼働状況やメンテナンス情報はTwitter（[@miu200521358](https://twitter.com/miu200521358)）にて行っています。\n",
        "\n",
        "エラーになる、起動しない、などの場合、まずは現在の配布状況をご確認ください。\n",
        "\n",
        "リプやDM等でのお問い合わせも受け付けています。"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "NxA42Uase5hk"
      },
      "source": [
        "# MMD自動トレースキット準備"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "aCQg_tD0e9v0"
      },
      "source": [
        "このノートブックでは、MMD自動トレースの準備と実行を行います。\n",
        "\n",
        "\n",
        "画面左上の「＞」をクリックして下さい。目次が開きます。（既に開いている場合は次へ進んでください）\n",
        "\n",
        "![目次](https://drive.google.com/uc?export=view&id=1x8AdFNmsIQPrtYptBf_NXPRNBJF8ON8z)\n",
        "\n",
        "\n",
        "ノートブックを上から順に確認し、以下手順をひとつずつ実行してください。\n",
        "\n",
        "実行が必要なセルには番号を振ってあります。①から順番に実行してください。\n",
        "\n",
        "※　準備一括実行だけは番号が振れないので、③が抜けています。\n",
        "\n",
        "- **「①　環境設定」**\n",
        "  - ランタイムがGPUに変更できたことを確認します\n",
        "    - 変更のやり方は、導入編をご確認ください\n",
        "  - Tensorflowのバージョンを1.xに変更します\n",
        "  - 効果音を[効果音ラボ](https://soundeffect-lab.info/)様よりダウンロードします\n",
        "   - 準備や実際のトレース処理等、長い処理時に鳴らします\n",
        "   - 不要の場合は、ブラウザの音量をミュートにしてください\n",
        "- **「②　Googleドライブとの連携」**\n",
        "  - Googleドライブとの連携ができたことを確認します\n",
        "  - 連携のやり方は、導入編をご確認ください\n",
        "- **「③　準備一括実行」**\n",
        "    - 準備セクションのセルをすべて実行します\n",
        "      - この処理で、MMD自動トレースに必要なプログラムやデータがすべてcolab上に作成されます。\n",
        "      - 大体40～60分くらいかかります。\n",
        "- **「④　MMD自動トレースキット実行」**\n",
        "  - 実行セクションのセルを上から順番に1つずつ実行します\n",
        "    - トレース元動画の指定\n",
        "    - トレースパラメーターの設定\n",
        "    - トレース処理実行\n",
        "    - 人数にもよりますが、6000Fで大体50～60分くらいかかります。\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "F8qp5VzAWyGl"
      },
      "source": [
        "## 環境設定"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "UNrlmW0-W1D1"
      },
      "source": [
        "ヘッダの \"ランタイム\"　＞　\"ランタイムのタイプを変更\"　＞　\"GPU\"　を選択して下さい。\n",
        "\n",
        "変更できたら、下のセルを実行して下さい。"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "P3zDmyRDwRs0",
        "cellView": "form"
      },
      "source": [
        "#@markdown ■■■■■■■■■■■■■■■■■■\n",
        "\n",
        "#@markdown 【セル①】　\n",
        "#@markdown - ランタイムがGPUであることの確認\n",
        "#@markdown - Tensorflowのバージョンを 1.x に変更\n",
        "#@markdown - 効果音を[効果音ラボ](https://soundeffect-lab.info/)様よりダウンロード\n",
        "\n",
        "#@markdown ■■■■■■■■■■■■■■■■■■\n",
        "\n",
        "! echo --------------\n",
        "! echo 【A】 ランタイムをGPUに変更\n",
        "! echo --------------\n",
        "\n",
        "! nvcc --version\n",
        "! nvidia-smi\n",
        "\n",
        "! echo --------------\n",
        "! echo 【B】 Tensorflowのバージョンを 1.x に変更\n",
        "! echo --------------\n",
        "\n",
        "%tensorflow_version 1.x\n",
        "\n",
        "%tensorflow_version\n",
        "\n",
        "! echo --------------\n",
        "! echo 【C】 効果音をダウンロード\n",
        "! echo --------------\n",
        "\n",
        "! wget --no-check-certificate -c \"https://soundeffect-lab.info/sound/anime/mp3/sceneswitch1.mp3\"\n",
        "\n",
        "from IPython.display import Audio\n",
        "Audio(\"sceneswitch1.mp3\", autoplay=True)"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "oo-BfaAdw9cN"
      },
      "source": [
        "**【OK】**\n",
        "\n",
        "下記のように表示されて、最後に音が鳴ったら成功です。\n",
        "\n",
        "![GPU変更成功](https://drive.google.com/uc?export=view&id=1Iw-WeUzbN48jra98rHx9kYBcw9sHJwVe)\n",
        "\n",
        "---\n",
        "\n",
        "**【NG】**\n",
        "\n",
        "下記のように表示されていたら、ランタイムの変更に失敗しているので、導入編を再度確認して、ランタイムを変更してください。\n",
        "\n",
        "![GPU切り替え失敗](https://drive.google.com/uc?export=view&id=1tufSuT7ocWxv3HkrmA5kwlemhu0gv6Je)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "o8OpmLpVp4qr"
      },
      "source": [
        "## Googleドライブ・GoogleSDKとの連携"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "FmdrRx_Tp8Bk"
      },
      "source": [
        "Googleドライブの `autotrace` フォルダと連携します。\n",
        "\n",
        "下のセルを実行してください。"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "_f1KFUn_qGsU",
        "cellView": "form"
      },
      "source": [
        "#@markdown ■■■■■■■■■■■■■■■■■■\n",
        "\n",
        "#@markdown 【セル②】　Googleドライブとの連携\n",
        "\n",
        "#@markdown ■■■■■■■■■■■■■■■■■■\n",
        "\n",
        "from google.colab import drive\n",
        "import os\n",
        "\n",
        "# Googleドライブマウント\n",
        "drive.mount('/gdrive')\n",
        "\n",
        "# 起点ディレクトリ\n",
        "base_path = \"/gdrive/My Drive/autotrace\"\n",
        "\n",
        "! echo \"autotraceフォルダの中身 -----------\"\n",
        "! ls -l \"$base_path\"\n",
        "! echo \"--------------------\""
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "ARzZFGmamXUr"
      },
      "source": [
        "**【OK】**\n",
        "\n",
        "下記のように、「autotrace」フォルダの中身が表示されていたら成功です。\n",
        "\n",
        "![Googleドライブ連携](https://drive.google.com/uc?export=view&id=19OhLvcyP-CN90KWDmkmBuSRR3BpO5GzV)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "vywRcK-urCEb"
      },
      "source": [
        "miuのGoogleドライブから必要なデータをDLするため、`GoogleSDK` と連携します。\n",
        "\n",
        "セル②と同じく、URLからアクセス許可を与えてください。\n",
        "\n",
        "下のセルを実行してください。"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "g1JzWWUvphNq",
        "cellView": "form"
      },
      "source": [
        "#@markdown ■■■■■■■■■■■■■■■■■■\n",
        "\n",
        "#@markdown 【セル③】　GoogleSDKとの連携\n",
        "\n",
        "#@markdown ■■■■■■■■■■■■■■■■■■\n",
        "\n",
        "# Googleドライブアクセスライブラリ\n",
        "!pip install -U -q PyDrive\n",
        "\n",
        "from pydrive.auth import GoogleAuth\n",
        "from pydrive.drive import GoogleDrive\n",
        "from google.colab import auth\n",
        "from oauth2client.client import GoogleCredentials\n",
        " \n",
        "auth.authenticate_user()\n",
        "gauth = GoogleAuth()\n",
        "gauth.credentials = GoogleCredentials.get_application_default()\n",
        "drive = GoogleDrive(gauth)\n",
        "\n",
        "! echo Google SDK との連携が成功しました。"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "38aL3FiVWvmN"
      },
      "source": [
        "## 準備一括実行"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "6k716wWUxT4F"
      },
      "source": [
        "ここでは、準備セクションのセルを一括で実行します。\n",
        "\n",
        "以下の手順を確認・実行して、準備一括実行セクションのセルをすべて実行してください。\n",
        "\n",
        "---\n",
        "\n",
        "目次の「MMD自動トレースキット実行」を選択して下さい。\n",
        "\n",
        "![実行選択](https://drive.google.com/uc?export=view&id=1YaSrtio06mmu94RUkU5dSolNtFqPiAnV)\n",
        "\n",
        "ヘッダの　\"ランタイム\"　＞　\"より前のセルを実行\"　を選択すると、準備セクションのすべてのセルが順次実行されます。\n",
        "\n",
        "最初に音が鳴りますが、処理が開始された音なので、同じ音が鳴るまで待って下さい。\n",
        "\n",
        "![すべてのセルを実行](https://drive.google.com/uc?export=view&id=1rIbVI_Qyjs8idEzkIR0IBIx6Dbp3te08)\n",
        "\n",
        "---\n",
        "\n",
        "** 【OK】**\n",
        "\n",
        "画面の一番下に、以下のように出力されれば、完了です。\n",
        "\n",
        "![処理成功](https://drive.google.com/uc?export=view&id=1D21xezv6QN0RQF5ZU_LR7PRnOk0Dw4Sc)\n",
        "\n",
        "大体40～60分くらいかかります。\n",
        "\n",
        "---\n",
        "\n",
        "**【NG】**\n",
        "\n",
        "![処理失敗](https://drive.google.com/uc?export=view&id=1t-immeF3Ji1_GBNatZOG1C07j42de4Rq)\n",
        "\n",
        "最後の行に、「No such file or directory」と出力されていたら失敗です。\n",
        "\n",
        "解決方法が分からない場合、ノートブックを共有してください。"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "E-h6RWCXnZU8"
      },
      "source": [
        "### 環境設定"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "IPiDvSBanScr"
      },
      "source": [
        "# 処理時間計測のための開始時間\n",
        "import time\n",
        "start_time = time.time()"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "9UMIfs3snkRm"
      },
      "source": [
        "# Openposeバージョンタグ\n",
        "ver_openpose = \"v1.5.1\""
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "iWQcbt_rnblK"
      },
      "source": [
        "# MMD自動トレースキットバージョンタグ\n",
        "ver_tag = \"ver1.03.02\""
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "EK-WUxgciv9V"
      },
      "source": [
        "### cmake"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "Lw3SxfQuPoyc"
      },
      "source": [
        "! cmake --version"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "djxuuJjKix5B"
      },
      "source": [
        "! wget -c \"https://github.com/Kitware/CMake/releases/download/v3.17.2/cmake-3.17.2.tar.gz\"\n",
        "! tar xf cmake-3.17.2.tar.gz\n",
        "! cd cmake-3.17.2 && ./configure && make && sudo make install"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "Viqw8qJqfDyf"
      },
      "source": [
        "### Openpose"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "a-fnE9kwgcfg"
      },
      "source": [
        "# ライブラリのインストール\n",
        "\n",
        "# Basic\n",
        "! sudo apt-get --assume-yes update\n",
        "! sudo apt-get --assume-yes install build-essential\n",
        "# OpenCV\n",
        "! sudo apt-get --assume-yes install libopencv-dev\n",
        "# General dependencies\n",
        "! sudo apt-get --assume-yes install libatlas-base-dev libprotobuf-dev libleveldb-dev libsnappy-dev libhdf5-serial-dev protobuf-compiler\n",
        "! sudo apt-get --assume-yes install --no-install-recommends libboost-all-dev\n",
        "# Remaining dependencies, 14.04\n",
        "! sudo apt-get --assume-yes install libgflags-dev libgoogle-glog-dev liblmdb-dev\n",
        "# Python3 libs\n",
        "! sudo apt-get --assume-yes install python3-setuptools python3-dev build-essential\n",
        "! sudo apt-get --assume-yes install python3-pip\n",
        "! sudo -H pip3 install --upgrade numpy protobuf opencv-python\n",
        "# OpenCL Generic\n",
        "! sudo apt-get --assume-yes install opencl-headers ocl-icd-opencl-dev\n",
        "! sudo apt-get --assume-yes install libviennacl-dev"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "eMCKuBuagoFo"
      },
      "source": [
        "#  Openpose の clone\n",
        "! git clone  --depth 1 -b \"$ver_openpose\" https://github.com/CMU-Perceptual-Computing-Lab/openpose.git \n",
        "# ! git clone  --depth 1 https://github.com/CMU-Perceptual-Computing-Lab/openpose.git     "
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "QCg6Wp-ta8mg"
      },
      "source": [
        "# OpenposeモデルデータDL\n",
        "! rm -r ./openpose/models\n",
        "\n",
        "# Openposeモデルデータ の導入\n",
        "! mkdir -p ./openpose/models\n",
        "\n",
        "# Openposeモデルデータのダウンロード\n",
        "downloaded = drive.CreateFile({'id': '1-XlC0b00ueiS8-fDqKeS8w5NQ35DOnFN'})\n",
        "downloaded.GetContentFile('opnepose-models.zip')\n",
        "\n",
        "! unzip ./opnepose-models.zip\n",
        "! mv ./models ./openpose"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "kDFYUPslKCBX"
      },
      "source": [
        "# Create build directory\n",
        "! cd openpose && mkdir build && cd build"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "440sxTDeKFSh"
      },
      "source": [
        "# Scenario 1 - Caffe not installed and OpenCV installed using apt-get\n",
        "# ! cd openpose/build && cmake .. -D DOWNLOAD_BODY_COCO_MODEL=ON\n",
        "! cd openpose/build && cmake .. "
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "BSls4lfOgwG0"
      },
      "source": [
        "# Openpose BUilding\n",
        "! cd openpose/build && make -j`nproc`"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "lZLayojmhDdI"
      },
      "source": [
        "### mannequinchallenge-vmd"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "rJw3lnjKhIp7"
      },
      "source": [
        "# mannequinchallenge-vmd の clone\n",
        "! git clone  --depth 1 -b \"$ver_tag\" https://github.com/miu200521358/mannequinchallenge-vmd.git"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "sNbLo-sBhlcL"
      },
      "source": [
        "# mannequinchallenge-vmd の モデルデータDL\n",
        "\n",
        "# モデルデータのダウンロード\n",
        "! cd  ./mannequinchallenge-vmd && ./fetch_checkpoints.sh"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "Gvkd3YfCiVJ8"
      },
      "source": [
        "### 3d-pose-baseline-vmd"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "w3Uh4e6liYPg"
      },
      "source": [
        "# 3d-pose-baseline-vmd の clone\n",
        "! git clone  --depth 1 -b \"$ver_tag\" https://github.com/miu200521358/3d-pose-baseline-vmd.git"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "Iw7kI9zhi_7k"
      },
      "source": [
        "# 3d-pose-baseline-vmd の Human3.6MモデルデータDL\n",
        "\n",
        "# Human3.6Mモデルデータ の導入\n",
        "! mkdir -p ./3d-pose-baseline-vmd/data/h36m\n",
        "\n",
        "# Human3.6Mモデルデータのダウンロード\n",
        "downloaded = drive.CreateFile({'id': '1W5WoWpCcJvGm4CHoUhfIB0dgXBDCEHHq'})\n",
        "downloaded.GetContentFile('h36m.zip')\n",
        "\n",
        "! unzip ./h36m.zip\n",
        "\n",
        "! mv ./h36m ./3d-pose-baseline-vmd/data/"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "dclND00zjGdN"
      },
      "source": [
        "# 3d-pose-baseline-vmd の 学習データDL\n",
        "\n",
        "# 3d-pose-baseline用学習データ の導入\n",
        "! mkdir -p ./3d-pose-baseline-vmd/experiments\n",
        "\n",
        "# Human3.6Mモデルデータのダウンロード\n",
        "downloaded = drive.CreateFile({'id': '1v7ccpms3ZR8ExWWwVfcSpjMsGscDYH7_'})\n",
        "downloaded.GetContentFile('experiments.zip')\n",
        "\n",
        "! unzip ./experiments.zip\n",
        "\n",
        "! mv ./experiments ./3d-pose-baseline-vmd/"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "jruMP1J4jLXX"
      },
      "source": [
        "### VMD-3d-pose-baseline-multi"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "87ZPjj6IjPgj"
      },
      "source": [
        "# VMD-3d-pose-baseline-multi の clone\n",
        "\n",
        "! git clone  --depth 1 -b \"$ver_tag\" https://github.com/miu200521358/VMD-3d-pose-baseline-multi.git"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "fnuSwMT9jW5E"
      },
      "source": [
        "# VMD-3d-pose-baseline-multi のライブラリ\n",
        "\n",
        "! sudo apt-get install python3-pyqt5  \n",
        "! sudo apt-get install pyqt5-dev-tools\n",
        "! sudo apt-get install qttools5-dev-tools"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "GIp8lIjZY7ih"
      },
      "source": [
        "### 準備結果確認"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "T8vXn_ZE6bHk"
      },
      "source": [
        "# サンプルの実行確認\n",
        "! cd openpose && ./build/examples/openpose/openpose.bin --video examples/media/video.avi --write_json ./output/ --display 0  --write_video ./output/openpose.avi --model_pose COCO"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "gZjjbPz0llYs"
      },
      "source": [
        "import time\n",
        "\n",
        "elapsed_time = (time.time() - start_time) / 60\n",
        "\n",
        "! echo \"■■■■■■■■■■■■■■■■■■■■■■■■\"\n",
        "! echo \"■■すべての処理が終了しました\"\n",
        "! echo \"■■\"\n",
        "! echo \"■■処理にかかった時間：\" \"$elapsed_time\" \"分\"\n",
        "! echo \"■■■■■■■■■■■■■■■■■■■■■■■■\"\n",
        "\n",
        "! echo \"Openpose実行結果\"\n",
        "\n",
        "! ls -l ./openpose/output/openpose.avi\n",
        "\n",
        "from IPython.display import Audio\n",
        "Audio(\"sceneswitch1.mp3\", autoplay=True)"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "IrnCtUv8XohO"
      },
      "source": [
        "# MMD自動トレースキット実行"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "3g59mu0Q5fC8"
      },
      "source": [
        "## インストール完了確認"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "l5-4naWjXqUo"
      },
      "source": [
        "ここからは、キットを実際に実行していきます。\n",
        "\n",
        "「より前のセルを実行する」で、インストールはすべて実行されましたでしょうか。\n",
        "\n",
        "詳しくは、「準備開始」のセクションを確認してください。\n",
        "\n",
        "準備完了されましたら、下のセルを実行して、インストールがすべて完了しているか確認してください。\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "soBmKdn_KjW5",
        "cellView": "form"
      },
      "source": [
        "#@markdown ■■■■■■■■■■■■■■■■■■\n",
        "\n",
        "#@markdown 【セル⑤】　インストール完了確認\n",
        "\n",
        "#@markdown ※④は準備一括実行なので項番抜けています。\n",
        "\n",
        "#@markdown ■■■■■■■■■■■■■■■■■■\n",
        "\n",
        "\n",
        "!ls -l ./openpose/README.md\n",
        "!ls -l ./mannequinchallenge-vmd/README.md\n",
        "!ls -l ./3d-pose-baseline-vmd/README.md\n",
        "!ls -l ./VMD-3d-pose-baseline-multi/README.md\n",
        "!ls -l ./openpose/output/openpose.avi"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "Dd1C8N7iL4ZJ"
      },
      "source": [
        "**【OK】**\n",
        "\n",
        "以下のように、ファイル名とファイルサイズが表示されていれば、インストール完了です。(日時は米時間のようです)\n",
        "\n",
        "入力映像ファイルアップロードに進んでください。\n",
        "\n",
        "![インストール成功](https://drive.google.com/uc?export=view&id=1l13A2iF9oTpGcZSe9q8k7JyDyiABxOQT)\n",
        "\n",
        "---\n",
        "\n",
        "**【NG】**\n",
        "\n",
        "以下のように、「No such file or directory」と表示されている場合、インストール失敗です。\n",
        "\n",
        "![インストール失敗](https://drive.google.com/uc?export=view&id=1LuKoSMwFOzFg8NguFxqAtmQy9B1_KMXr)\n",
        "\n",
        "このノートブックの先頭に戻って初めから実行し直してください。\n",
        "\n",
        "３回やってもインストールに失敗する場合、ノートブックを共有してください。"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "4R8ogPNZXtQc"
      },
      "source": [
        "## 入力映像ファイルアップロード"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "FrglOLBZXv9B"
      },
      "source": [
        "処理したい映像ファイルを、準備してください。\n",
        "\n",
        " - ファイル名は **半角英数字のみ** にしてください。opencvは2バイト文字を読み込めません。\n",
        " - Googleドライブの **autotrace** フォルダ 直下に置いてください。\n",
        " - FPSは、**30fps** もしくは **60fps** にしてください。\n",
        " - 大きさは、**1280x720** にしてください。\n",
        " - 大きさもしくは fps が指定通りではない場合、プログラム側で再エンコードします。（fpsは30になります）\n",
        " - **マウント後のGooleドライブ上のファイルの上書きや更新は正しく認識されません。** 新しいファイルは新規の名前でアップロードしてから処理して下さい。\n",
        " - アップロードが完了したら、下のセルを順次実行して下さい。"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "WQxj2Y6-Zutl",
        "cellView": "form"
      },
      "source": [
        "#@markdown ■■■■■■■■■■■■■■■■■■\n",
        "\n",
        "#@markdown 【セル⑥】　入力映像ファイルアップロード\n",
        "\n",
        "#@markdown ■■■■■■■■■■■■■■■■■■\n",
        "\n",
        "\n",
        "#@markdown ### 【O】入力映像ファイル\n",
        "#@markdown 解析対象となる映像のファイルの名前を入力して下さい。\n",
        "\n",
        "#@markdown 横幅が1280ではない、もしくは30fpsではない場合、再エンコードします。\n",
        "\n",
        "input_video_name = \"input.mp4\"  #@param {type: \"string\"}\n",
        "\n",
        "from google.colab import drive\n",
        "import sys\n",
        "import os\n",
        "import cv2\n",
        "import datetime\n",
        "import math\n",
        "from tqdm import tqdm\n",
        "from PIL import Image\n",
        "import traceback\n",
        "import numpy as np\n",
        "import shutil\n",
        "import re\n",
        "import glob\n",
        "\n",
        "# Googleドライブマウント\n",
        "drive.mount('/gdrive')\n",
        "\n",
        "# 起点ディレクトリ\n",
        "base_path = \"/gdrive/My Drive/autotrace\"\n",
        "\n",
        "! echo \"autotraceフォルダの中身 -----------\"\n",
        "! ls -l \"$base_path\"\n",
        "! echo \"--------------------\"\n",
        "\n",
        "# 入力動画ファイル\n",
        "input_video = base_path + \"/\"+ input_video_name\n",
        "\n",
        "print(\"ファイル名: \", os.path.basename(input_video))\n",
        "print(\"ファイルサイズ: \", os.path.getsize(input_video))\n",
        "\n",
        "def numericalSort(value):\n",
        "    numbers = re.compile(r'(\\d+)')\n",
        "    parts = numbers.split(value)\n",
        "    parts[1::2] = map(int, parts[1::2])\n",
        "    return parts\n",
        "\n",
        "video = cv2.VideoCapture(input_video)\n",
        "# 幅\n",
        "W = video.get(cv2.CAP_PROP_FRAME_WIDTH)\n",
        "# 高さ\n",
        "H = video.get(cv2.CAP_PROP_FRAME_HEIGHT)\n",
        "# 総フレーム数\n",
        "count = video.get(cv2.CAP_PROP_FRAME_COUNT)\n",
        "# fps\n",
        "fps = video.get(cv2.CAP_PROP_FPS)\n",
        "\n",
        "print(\"横: {0}, 縦: {1}, フレーム数: {2}, fps: {3}\".format(W, H, count, fps))\n",
        "\n",
        "# マネキン用に固定\n",
        "width = 1280\n",
        "height = 720\n",
        "\n",
        "# 画面比率\n",
        "aspect = width / height\n",
        "\n",
        "if (aspect != (9/6) and aspect != (16/9)) or W != 1280 or H != 720 or (fps != 30 and fps != 60):\n",
        "    print(\"大きさもしくはfpsが処理対象外のため、再エンコードします: \"+ input_video)\n",
        "    \n",
        "    if os.path.exists(\"./resize_img/\"):\n",
        "        shutil.rmtree(\"./resize_img/\")\n",
        "\n",
        "    if os.path.exists(\"./interpolation_img/\"):\n",
        "        shutil.rmtree(\"./interpolation_img/\")\n",
        "\n",
        "    # フォルダ生成\n",
        "    os.mkdir(\"./resize_img/\")\n",
        "    os.mkdir(\"./interpolation_img/\")\n",
        "\n",
        "    # リサイズpng出力先\n",
        "    resize_img_path = \"./resize_img/resize{:012}.png\"\n",
        "    # 補間png出力先\n",
        "    interpolation_output_path = \"./interpolation_img/interpolation_{:012}.png\"\n",
        "\n",
        "    # 縮尺\n",
        "    scale = width / W\n",
        "\n",
        "    # オリジナル高さ\n",
        "    im_height = int(H * scale)\n",
        "\n",
        "    # 出力ファイルパス\n",
        "    out_name = 'recode_{0}.mp4'.format(\"{0:%Y%m%d_%H%M%S}\".format(datetime.datetime.now()))\n",
        "    out_path = '{0}/{1}'.format(base_path, out_name)\n",
        "    cnt = 0\n",
        "\n",
        "    try:\n",
        "        fourcc = cv2.VideoWriter_fourcc(*\"MP4V\")\n",
        "        out = cv2.VideoWriter(out_path, fourcc, 30.0, (width, height))\n",
        "        # 入力ファイル\n",
        "        cap = cv2.VideoCapture(input_video)\n",
        "\n",
        "        print (\"■■■■■元動画読み込み開始\")\n",
        "\n",
        "        for n in range(int(count)):\n",
        "        # for _ in tqdm(range(int(count))):\n",
        "            if not cap.isOpened():\n",
        "                break\n",
        "\n",
        "            # 動画から1枚キャプチャして読み込む\n",
        "            flag, frame = cap.read()  # Capture frame-by-frame\n",
        "\n",
        "            # 動画が終わっていたら終了\n",
        "            if flag == False:\n",
        "                break\n",
        "\n",
        "            # 画像の縦横を指定サイズに変形\n",
        "            img = Image.fromarray(frame)\n",
        "            img = img.resize((width, im_height),Image.ANTIALIAS)\n",
        "\n",
        "            # 黒く塗りつぶす用の背景画像を作成\n",
        "            bg = Image.new(\"RGB\",[width,height],(0,0,0))\n",
        "\n",
        "            # 元の画像を、背景画像のセンターに配置\n",
        "            bg.paste(img,(int((width-img.size[0])/2),int((height-img.size[1])/2)))\n",
        "\n",
        "            # opencv用に変換\n",
        "            out_frame = np.asarray(bg)\n",
        "\n",
        "            # PNG出力\n",
        "            cv2.imwrite(resize_img_path.format(n), out_frame)\n",
        "\n",
        "            if n % 100 == 0:\n",
        "                print (\"-- 元動画読み込み中(%s)\" % n)\n",
        "\n",
        "        print (\"■■■■■元動画読み込み終了\")\n",
        "\n",
        "        # フレーム補間用比率\n",
        "        fps_interpolation = fps / 30\n",
        "\n",
        "        print(\"■■■■■補間生成開始\")\n",
        "        cnt = 0\n",
        "\n",
        "        # 最後の１つ手前（補間ができる状態）までループ\n",
        "        # for _ in tqdm(range(round(count * (30 / fps)) - 1)):\n",
        "        for _ in range(round(count * (30 / fps)) - 1):\n",
        "            # 補間した出力CNT\n",
        "            inter_cnt = cnt * fps_interpolation\n",
        "            # INDEXと比率（整数部と小数部）\n",
        "            inter_cnt_rate, inter_cnt_idx = math.modf(inter_cnt)\n",
        "            # print(\"フレーム補間: %s -> %s, idx: %s, rate: %s\" % ( cnt, inter_cnt, inter_cnt_idx, inter_cnt_rate ))\n",
        "\n",
        "            # 前のフレーム\n",
        "            past_frame = cv2.imread(resize_img_path.format(int(inter_cnt_idx)))\n",
        "            # 今回のフレーム\n",
        "            now_frame = cv2.imread(resize_img_path.format(int(inter_cnt_idx + 1)))\n",
        "\n",
        "            # 混ぜ合わせる比率\n",
        "            past_rate = inter_cnt_rate\n",
        "            now_rate = 1 - inter_cnt_rate\n",
        "\n",
        "            # フレーム補間をして出力する\n",
        "            target_output_frame = cv2.addWeighted(past_frame, past_rate, now_frame, now_rate, 0)\n",
        "\n",
        "            # PNG出力\n",
        "            cv2.imwrite(interpolation_output_path.format(cnt), target_output_frame)\n",
        "\n",
        "            cnt += 1\n",
        "\n",
        "            if cnt % 100 == 0:\n",
        "                print (\"-- 補間生成中(%s)\" % cnt)\n",
        "\n",
        "        print(\"■■■■■補間生成終了\")\n",
        "\n",
        "        # 最後にnowを出力\n",
        "        cv2.imwrite(interpolation_output_path.format(cnt), now_frame)\n",
        "\n",
        "        print(\"■■■■■結合開始\")\n",
        "\n",
        "        # 結合開始\n",
        "        for n, file_path in enumerate(sorted(glob.glob('./interpolation_img/interpolation_*.png'), key=numericalSort)):\n",
        "            # フレーム\n",
        "            frame = cv2.imread(file_path)\n",
        "\n",
        "            # 動画出力\n",
        "            out.write(frame)\n",
        "\n",
        "            if n % 100 == 0:\n",
        "                print (\"-- 結合中(%s)\" % n)\n",
        "\n",
        "        print(\"■■■■■結合終了\")\n",
        "\n",
        "        # 終わったら開放\n",
        "        out.release()\n",
        "        cap.release()\n",
        "    except Exception as e:\n",
        "        print(\"再エンコード失敗\", e)\n",
        "        print(traceback.format_exc())\n",
        "\n",
        "    cv2.destroyAllWindows()\n",
        "    \n",
        "    print('MMD入力用MP4ファイル再生成', out_path)\n",
        "    input_video_name = out_name\n",
        "\n",
        "    # 入力動画ファイル再設定\n",
        "    input_video = base_path + \"/\"+ input_video_name\n",
        "    \n",
        "    video = cv2.VideoCapture(input_video)\n",
        "    # 幅\n",
        "    W = video.get(cv2.CAP_PROP_FRAME_WIDTH)\n",
        "    # 高さ\n",
        "    H = video.get(cv2.CAP_PROP_FRAME_HEIGHT)\n",
        "    # 総フレーム数\n",
        "    count = video.get(cv2.CAP_PROP_FRAME_COUNT)\n",
        "    # fps\n",
        "    fps = video.get(cv2.CAP_PROP_FPS)\n",
        "\n",
        "    print(\"【再チェック】横: {0}, 縦: {1}, フレーム数: {2}, fps: {3}\".format(W, H, count, fps))\n",
        "\n",
        "!echo \"入力映像ファイルは\" \"$input_video_name\" \"です。\"\n",
        "!echo \"\"\n",
        "!echo \"問題なければ、次へ進んで下さい。\"\n",
        "\n",
        "from IPython.display import Audio\n",
        "Audio(\"sceneswitch1.mp3\", autoplay=True)"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "LXcgFDk-YDMB"
      },
      "source": [
        "最後のファイル名が取得できていたら成功です。\n",
        "\n",
        "---\n",
        "**【OK】**\n",
        "\n",
        "ファイルの大きさとfpsが指定通りの場合、入力ファイルをそのまま扱います。\n",
        "\n",
        "![OK](https://drive.google.com/uc?export=view&id=1lvOhCAj99_NUNDb-wfRAxeu-o0Exth7v)\n",
        "\n",
        "----\n",
        "**【再エンコード】**\n",
        "\n",
        "ファイルの大きさとfpsが指定通りではない場合、再エンコードしたmp4ファイルを入力ファイルとして扱います。\n",
        "\n",
        "![再エンコード](https://drive.google.com/uc?export=view&id=1xEiy-pdeHWQpt4CLZePg9YT1_7U8bEqz)\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "8qMeT79QYFeC"
      },
      "source": [
        "## パラメーター設定"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "AFlJGTLmFLXE"
      },
      "source": [
        "パラメーターを設定して下さい。\n",
        "\n",
        " - 【O】… Openposeで使用するパラメーター\n",
        " - 【M】… 深度推定（mannequinchallenge-vmd）で使用するパラメーター\n",
        " - 【V】… VMD生成（VMD-3d-pose-baseline-multi）で使用するパラメーター"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "FQ3yCAl8YI1o",
        "cellView": "form"
      },
      "source": [
        "#@markdown ■■■■■■■■■■■■■■■■■■\n",
        "\n",
        "#@markdown 【セル⑦】　パラメーター設定\n",
        "\n",
        "#@markdown ■■■■■■■■■■■■■■■■■■\n",
        "\n",
        "\n",
        "#@markdown 映像をトレースする際のパラメーターを入力して、セルを実行して下さい。\n",
        "\n",
        "#@markdown --- \n",
        "\n",
        "#@markdown ### 【O】映像に映っている最大人数\n",
        "#@markdown 映像から取得したい人数を入力して下さい。\n",
        "#@markdown できるだけこの人数分映っているように、映像データを加工しておいてください。\n",
        "#@markdown 交差などで多少映ってない分には大体フォローできます。\n",
        "number_people_max =   1#@param {type: \"number\"}\n",
        "\n",
        "#@markdown --- \n",
        "\n",
        "#@markdown ### 【O】解析を開始するフレーム\n",
        "#@markdown 解析を開始するフレームNoを入力して下さい。(0始まり)\n",
        "#@markdown 最初にロゴが表示されている等、人体が正確にトレースできない場合に、全員が映像内に映っている最初のフレームを指定してください。\n",
        "frame_first = 0  #@param {type: \"number\"}\n",
        "\n",
        "#@markdown ---\n",
        "\n",
        "#@markdown ### 【M】解析を終了するフレーム\n",
        "#@markdown 解析を終了するフレームNoを入力して下さい。(0始まり)\n",
        "#@markdown 【深度推定】で反転や順番を調整する際に、最後まで出力せずとも処理を終了して結果を見ることができます。\n",
        "#@markdown デフォルト値の「-1」だと、最後まで解析を行います。\n",
        "end_frame_no = -1  #@param {type: \"number\"}\n",
        "\n",
        "#@markdown --- \n",
        "\n",
        "#@markdown ### 【M】反転指定リスト\n",
        "#@markdown Openposeが誤認識して反転しているフレーム番号(0始まり)、人物INDEX順番、反転の内容を指定してください。\n",
        "#@markdown Openposeが0F目で認識した順番に0, 1, とINDEXが割り当てられます。\n",
        "#@markdown フォーマット：［＜フレーム番号＞:反転を指定したい人物INDEX,<反転内容>］\n",
        "#@markdown <反転内容>: R: 全身反転, U: 上半身反転, L: 下半身反転, N: 反転なし\n",
        "#@markdown 例）[10:1,R]　…　10F目の1番目の人物を全身反転します。\n",
        "#@markdown message.logに上記フォーマットで、反転出力した場合にその内容を出力しているので、それを参考にしてください。\n",
        "#@markdown [10:1,R][30:0,U]のように、カッコ単位で複数件指定可能です。\n",
        "reverse_specific = \"\"  #@param {type: \"string\"}\n",
        "\n",
        "#@markdown --- \n",
        "\n",
        "#@markdown ### 【M】順番指定リスト\n",
        "#@markdown 複数人数トレースで、交差後の人物INDEX順番を指定してください。1人トレースの場合は空欄のままで大丈夫です。\n",
        "#@markdown Openposeが0F目で認識した順番に0, 1, とINDEXが割り当てられます。\n",
        "#@markdown フォーマット：［＜フレーム番号＞:0番目に推定された人物のインデックス,1番目に推定された人物のインデックス, …］\n",
        "#@markdown 例）[10:1,0]　…　10F目は、左から1番目の人物、0番目の人物の順番に並べ替えます。\n",
        "#@markdown message.logに上記フォーマットで、どのような順番で出力したかを残しているので、それを参考にしてください。\n",
        "#@markdown [10:1,0][30:0,1]のように、カッコ単位で複数件指定可能です。\n",
        "#@markdown また、output_XXX.aviでは、推定された順番に人物に色が割り当てられています。体の右半分は赤、左半分は以下の色になります。\n",
        "#@markdown 0:緑, 1:青, 2:白, 3:黄, 4:桃,  5:水色, 6:濃緑, 7:濃青, 8:灰色, 9:濃黄, 10:濃桃, 11:濃水色\n",
        "order_specific = \"\"  #@param {type: \"string\"}\n",
        "\n",
        "#@markdown --- \n",
        "\n",
        "#@markdown ### 【V】ボーン構造CSVファイル\n",
        "#@markdown トレース対象モデルのボーン構造CSVファイルのパスを選択もしくは入力して下さい。\n",
        "#@markdown あにまさ式ミクと、あにまさ式ミク準標準が選べる他、任意のモデルのボーン構造CSVファイルが入力可能です。\n",
        "#@markdown 任意のモデルボーン構造CSVファイルを入力する場合、Googleドライブの \"autotrace\" フォルダにcsvファイルをアップロードしてください。\n",
        "#@markdown そしてcsvファイル名を入力して下さい。\n",
        "#@markdown [モデルボーン構造CSVファイル出力方法](https://github.com/miu200521358/VMD-3d-pose-baseline-multi/blob/master/born/README.md)\n",
        "born_model_csv = \"born/\\u3042\\u306B\\u307E\\u3055\\u5F0F\\u30DF\\u30AF\\u6E96\\u6A19\\u6E96\\u30DC\\u30FC\\u30F3.csv\" #@param [\"born/\\u3042\\u306B\\u307E\\u3055\\u5F0F\\u30DF\\u30AF\\u30DC\\u30FC\\u30F3.csv\", \"born/\\u3042\\u306B\\u307E\\u3055\\u5F0F\\u30DF\\u30AF\\u6E96\\u6A19\\u6E96\\u30DC\\u30FC\\u30F3.csv\"] {allow-input: true}\n",
        "\n",
        "\n",
        "#@markdown --- \n",
        "\n",
        "#@markdown ### 【V】IKで出力するか\n",
        "#@markdown 足をIKで出力するか、yes か no を選んで下さい。\n",
        "#@markdown no を入力した場合、FKで出力します\n",
        "ik_flag = \"yes\"  #@param ['yes', 'no']\n",
        "is_ik = 1 if ik_flag == \"yes\" else 0\n",
        "\n",
        "#@markdown ---\n",
        "\n",
        "#@markdown ### 【V】踵位置補正\n",
        "#@markdown 踵のY軸補正値を数値(小数可)で入力して下さい。\n",
        "#@markdown マイナス値を入力すると地面に近付き、プラス値を入力すると地面から遠ざかります。\n",
        "#@markdown ある程度は自動で補正しますが、補正しきれない場合に、設定して下さい。\n",
        "heel_position = 0.0  #@param {type: \"number\"}\n",
        "\n",
        "#@markdown ---\n",
        "\n",
        "#@markdown ### 【V】センターZ移動倍率\n",
        "#@markdown センターZ移動に掛ける倍率を数値(小数可)で入力して下さい。\n",
        "#@markdown 値が小さいほど、センターZ移動の幅が小さくなります。\n",
        "#@markdown 0を入力した場合、センターZ軸移動を行いません。\n",
        "center_z_scale = 1.5  #@param {type: \"number\"}\n",
        "\n",
        "#@markdown ---\n",
        "\n",
        "#@markdown ### 【V】センターZの滑らかさ\n",
        "#@markdown センターZの円滑化の度数を指定します\n",
        "#@markdown 1以上の整数のみを入力して下さい。\n",
        "#@markdown 度数が大きいほど、円滑化されます。（代わりに動作が小さくなります）\n",
        "depth_smooth_times = 4  #@param {type: \"number\"}\n",
        "\n",
        "#@markdown ---\n",
        "\n",
        "#@markdown ### 【V】滑らかさ\n",
        "#@markdown モーションの円滑化の度数を指定します\n",
        "#@markdown 1以上の整数のみを入力して下さい。\n",
        "#@markdown 度数が大きいほど、円滑化されます。（代わりに動作が小さくなります）\n",
        "smooth_times = 1  #@param {type: \"number\"}\n",
        "\n",
        "#@markdown ---\n",
        "\n",
        "#@markdown ### 【V】移動間引き量\n",
        "#@markdown 移動キー（IK・センター）の間引きに使用する移動量を数値(小数可)で指定します\n",
        "#@markdown 指定された範囲内の移動があった場合に間引きされます。\n",
        "#@markdown 移動間引き量を0にした場合、間引きを行いません。\n",
        "threshold_pos = 0.5  #@param {type: \"number\"}\n",
        "\n",
        "#@markdown ---\n",
        "\n",
        "#@markdown ### 【V】回転間引き角度\n",
        "#@markdown 回転キーの間引きに使用する角度(0～180度まで小数可)を指定します\n",
        "#@markdown 指定された角度以内の回転があった場合に間引きされます。\n",
        "threshold_rot = 5  #@param {type: \"number\"}\n",
        "\n",
        "import os\n",
        "if not os.path.exists(\"./VMD-3d-pose-baseline-multi/{0}\".format(born_model_csv)):\n",
        "    # 既存のボーン構造CSVでない場合、ドライブの下を参照\n",
        "    born_model_csv = \"/gdrive/My Drive/autotrace/{0}\".format(born_model_csv)\n",
        "    if not os.path.exists(born_model_csv):\n",
        "        !echo ■■■■■■■■■■■■■■■■\n",
        "        !echo ■ WARNING\n",
        "        !echo ■ ボーン構造CSVが見つかりません。ファイル名を確認してください。\n",
        "        !echo ■ \"$born_model_csv\"\n",
        "        !echo ■■■■■■■■■■■■■■■■\n",
        "\n",
        "!echo 【O】映像に映っている最大人数: \"$number_people_max\"\n",
        "!echo 【O】解析を開始するフレーム: \"$frame_first\"\n",
        "!echo 【M】解析を終了するフレーム: \"$end_frame_no\"\n",
        "!echo 【M】反転指定リスト: \"$reverse_specific\"\n",
        "!echo 【M】順番指定リスト: \"$order_specific\"\n",
        "!echo 【V】ボーン構造CSVファイル: \"$born_model_csv\"\n",
        "!echo 【V】IKで出力するか: \"$ik_flag\"\n",
        "!echo 【V】踵位置補正: \"$heel_position\"\n",
        "!echo 【V】センターZ移動倍率: \"$center_z_scale\"\n",
        "!echo 【V】センターZ滑らかさ: \"$depth_smooth_times\"\n",
        "!echo 【V】滑らかさ: \"$smooth_times\"\n",
        "!echo 【V】移動間引き量: \"$threshold_pos\"\n",
        "!echo 【V】回転間引き角度: \"$threshold_rot\"\n",
        "\n",
        "!echo \"\"\n",
        "!echo 上記で間違いない場合、次に進んで下さい。\n"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "SFWBO6c0YLa4"
      },
      "source": [
        "## 自動トレース実行（全実行）"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "qVjcwTC-Ig4l",
        "cellView": "form"
      },
      "source": [
        "#@markdown ■■■■■■■■■■■■■■■■■■\n",
        "\n",
        "#@markdown 【セル⑧】　自動トレース実行（全実行）\n",
        "\n",
        "#@markdown ■■■■■■■■■■■■■■■■■■\n",
        "\n",
        "#@markdown フォームの入力がすべて完了したら、このセルを実行してください。\n",
        "#@markdown 以下の順番で処理が実行されます。\n",
        "\n",
        "#@markdown 1. Openpose（映像→2D）\n",
        "#@markdown 2. mannequinchallenge-vmd（深度推定、人物INDEX並び替え）\n",
        "#@markdown 3. 3d-pose-baseline-vmd（2D→3D）\n",
        "#@markdown 4. VMD-3d-pose-baseline-multi（3D→VMD）\n",
        "\n",
        "#@markdown トレース人数にもよりますが、6000Fで大体50～60分くらいかかります\n",
        "#@markdown Openposeが開始すると、しばらく細長い四角が出たまま動かなくなったように見えます。\n",
        "#@markdown 再生ボタンの周りがくるくる回っていたら、背後で処理は行われていますので、何も操作せずお待ちください。\n",
        "#@markdown vmdファイルが生成されていない、pos.txtの中身が空、error.txtだけがある、といった場合は、まずerror.txtの中身を確認して、「エラーが起きた場合」セクションを確認・実行して下さい。\n",
        "\n",
        "import time\n",
        "import datetime\n",
        "import cv2\n",
        "import shutil\n",
        "import glob\n",
        "from google.colab import drive\n",
        "\n",
        "start_time = time.time()\n",
        "\n",
        "# 出力フォルダ削除\n",
        "if os.path.exists(\"./output\"):\n",
        "    !rm -r ./output\n",
        "\n",
        "# 処理日時\n",
        "now_str = \"{0:%Y%m%d_%H%M%S}\".format(datetime.datetime.now())\n",
        "\n",
        "# Googleドライブマウント\n",
        "drive.mount('/gdrive')\n",
        "\n",
        "# 起点ディレクトリ\n",
        "drive_base_dir = \"/gdrive/My Drive/autotrace\"\n",
        "\n",
        "output_json = \"/content/output/json\"\n",
        "output_openpose_avi = \"/content/output/openpose.avi\"\n",
        "! mkdir -p \"$output_json\"\n",
        "\n",
        "# 出力用Googleドライブフォルダ\n",
        "drive_dir_path = drive_base_dir + \"/\" + now_str \n",
        "! mkdir -p \"$drive_dir_path\"\n",
        "\n",
        "! echo ------------------------------------------\n",
        "! echo Openpose\n",
        "! echo ------------------------------------------\n",
        "\n",
        "# Openpose実行\n",
        "! cd openpose/ && ./build/examples/openpose/openpose.bin --video \"$input_video\" --display 0 --model_pose COCO --write_json \"$output_json\" --write_video \"$output_openpose_avi\" --frame_first \"$frame_first\" --number_people_max \"$number_people_max\"\n",
        "\n",
        "! echo ------------------------------------------\n",
        "! echo mannequinchallenge-vmd\n",
        "! echo ------------------------------------------\n",
        "\n",
        "! cd mannequinchallenge-vmd && python predict_video.py --video_path \"$input_video\" --json_path \"$output_json\" --interval 20 --reverse_specific \"$reverse_specific\" --order_specific \"$order_specific\" --verbose 1 --now \"$now_str\" --avi_output \"yes\"  --number_people_max \"$number_people_max\" --end_frame_no \"$end_frame_no\" --input single_view --batchSize 1\n",
        "    \n",
        "# 深度結果コピー\n",
        "depth_dir_path =  output_json + \"_\" + now_str + \"_depth\"\n",
        "\n",
        "if os.path.exists( depth_dir_path + \"/error.txt\"):\n",
        "    \n",
        "    # エラー発生\n",
        "    ! cp \"$depth_dir_path\"/error.txt \"$drive_dir_path\"\n",
        "\n",
        "    ! echo \"■■■■■■■■■■■■■■■■■■■■■■■■\"\n",
        "    ! echo \"■■エラーが発生したため、処理を中断しました。\"\n",
        "    ! echo \"■■\"\n",
        "    ! echo \"■■■■■■■■■■■■■■■■■■■■■■■■\"\n",
        "\n",
        "    ! echo \"$drive_dir_path\" \"の error.txt の中身を確認してください。\"\n",
        "\n",
        "else:\n",
        "    \n",
        "    ! cp \"$depth_dir_path\"/*.avi \"$drive_dir_path\"\n",
        "    ! cp \"$depth_dir_path\"/message.log \"$drive_dir_path\"\n",
        "    ! cp \"$depth_dir_path\"/reverse_specific.txt \"$drive_dir_path\"\n",
        "    ! cp \"$depth_dir_path\"/order_specific.txt \"$drive_dir_path\"\n",
        "\n",
        "    for i in range(1, number_people_max+1):\n",
        "        %tensorflow_version 1.x\n",
        "\n",
        "        ! echo ------------------------------------------\n",
        "        ! echo 3d-pose-baseline-vmd [\"$i\"]\n",
        "        ! echo ------------------------------------------\n",
        "\n",
        "        target_name = \"_\" + now_str + \"_idx0\" + str(i)\n",
        "        target_dir = output_json + target_name\n",
        "\n",
        "        !cd ./3d-pose-baseline-vmd && python src/openpose_3dpose_sandbox_vmd.py --camera_frame --residual --batch_norm --dropout 0.5 --max_norm --evaluateActionWise --use_sh --epochs 200 --load 4874200 --gif_fps 30 --verbose 1 --openpose \"$target_dir\" --person_idx 1    \n",
        "\n",
        "        ! echo ------------------------------------------\n",
        "        ! echo VMD-3d-pose-baseline-multi [\"$i\"]\n",
        "        ! echo ------------------------------------------\n",
        "\n",
        "        ! cd ./VMD-3d-pose-baseline-multi && python main.py -v 2 -t \"$target_dir\" -b \"$born_model_csv\" -c 30 -z \"$center_z_scale\" -s \"$smooth_times\" -p \"$threshold_pos\" -r \"$threshold_rot\" -k \"$is_ik\" -e \"$heel_position\" -d \"$depth_smooth_times\"\n",
        "\n",
        "        # INDEX別結果コピー\n",
        "        idx_dir_path = drive_dir_path + \"/idx0\" + str(i)\n",
        "        ! mkdir -p \"$idx_dir_path\"\n",
        "        \n",
        "        # 日本語対策でpythonコピー\n",
        "        for f in glob.glob(target_dir +\"/*.vmd\"):\n",
        "            shutil.copy(f, idx_dir_path)\n",
        "        \n",
        "        ! cp \"$target_dir\"/pos.txt \"$idx_dir_path\"\n",
        "        ! cp \"$target_dir\"/start_frame.txt \"$idx_dir_path\"\n",
        "\n",
        "    # Googleドライブ再マウント\n",
        "    drive.mount('/gdrive')\n",
        "\n",
        "    elapsed_time = (time.time() - start_time) / 60\n",
        "\n",
        "    ! echo \"■■■■■■■■■■■■■■■■■■■■■■■■\"\n",
        "    ! echo \"■■すべての処理が終了しました\"\n",
        "    ! echo \"■■\"\n",
        "    ! echo \"■■処理にかかった時間：\" \"$elapsed_time\" \"分\"\n",
        "    ! echo \"■■■■■■■■■■■■■■■■■■■■■■■■\"\n",
        "\n",
        "    ! echo \"\"\n",
        "    ! echo \"MMD自動トレース実行結果\"\n",
        "\n",
        "    ! echo \"$drive_dir_path\"\n",
        "    ! ls -l \"$drive_dir_path\"\n",
        "\n",
        "from IPython.display import Audio\n",
        "Audio(\"sceneswitch1.mp3\", autoplay=True)    "
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "6mhinYooFuj1"
      },
      "source": [
        "## 自動トレース実行（部分実行）"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "WKNMqF4LF3zw"
      },
      "source": [
        "**「自動トレース実行（全実行）」**を全部終えた後、再度の実行が不要な場合は、これで終了です。\n",
        "\n",
        "何らかの修正を行いたい場合、必要に応じて、以下方法で再度トレースを行ってください。\n",
        "\n",
        "1. トレース元動画を変えたい場合\n",
        "  - 新動画を、**新しいファイル名**で、Googleドライブの**「autotrace」**フォルダにアップロード\n",
        "  - **「入力映像ファイルアップロード」**のセルを実行\n",
        "  - **「パラメーター設定」**のセルを実行\n",
        "  - **「自動トレース実行（全実行）」**のセルを実行\n",
        "  \n",
        "2. 【O】のパラメーターを変えたい場合\n",
        "  - **「パラメーター設定」**の【O】の値を変更\n",
        "  - **「パラメーター設定」**のセルを実行\n",
        "  - **「自動トレース実行（全実行）」**のセルを実行\n",
        "\n",
        "3. 【M】のパラメーターを変えたい場合\n",
        "  - **「パラメーター設定」**の【M】の値を変更\n",
        "  - **「パラメーター設定」**のセルを実行\n",
        "  - **「A) 自動トレース再実行（深度推定）」**のセルを実行\n",
        "  - 【M】のパラメーターに納得した場合\n",
        "      -  **「B) 自動トレース再実行（2D→3D）」**のセルを実行\n",
        "      - **「C) 自動トレース再実行（3D→VMD）」**のセルを実行\n",
        "\n",
        "4. 【V】のパラメーターを変えたい場合\n",
        "  - **「パラメーター設定」**の【V】の値を変更\n",
        "  - **「パラメーター設定」**のセルを実行\n",
        "  - **「C) 自動トレース再実行（3D→VMD）」**のセルを実行"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "EQUcMLsf3TcN"
      },
      "source": [
        "### A) 自動トレース再実行(深度推定)"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "yM2PNPpd3uai",
        "cellView": "form"
      },
      "source": [
        "#@markdown ■■■■■■■■■■■■■■■■■■\n",
        "\n",
        "#@markdown 【セル⑨-A】　自動トレース再実行(深度推定)\n",
        "\n",
        "#@markdown ■■■■■■■■■■■■■■■■■■\n",
        "\n",
        "#@markdown パラメーター設定のセルを実行したら、このセルを実行してください。\n",
        "\n",
        "#@markdown 全実行で深度推定が既に行われていると見なし、人物INDEX並び替え処理以降の処理を行います。\n",
        "\n",
        "import time\n",
        "import datetime\n",
        "import cv2\n",
        "import os\n",
        "from google.colab import drive\n",
        "\n",
        "start_time = time.time()\n",
        "\n",
        "# 過去深度結果\n",
        "past_depth_dir_path =  output_json + \"_\" + now_str + \"_depth\"\n",
        "\n",
        "# 処理日時\n",
        "now_str = \"{0:%Y%m%d_%H%M%S}\".format(datetime.datetime.now())\n",
        "\n",
        "# Googleドライブマウント\n",
        "drive.mount('/gdrive')\n",
        "\n",
        "# 起点ディレクトリ\n",
        "drive_base_dir = \"/gdrive/My Drive/autotrace\"\n",
        "\n",
        "output_json = \"/content/output/json\"\n",
        "output_openpose_avi = \"/content/output/openpose.avi\"\n",
        "\n",
        "# 出力用Googleドライブフォルダ\n",
        "drive_dir_path = drive_base_dir + \"/\" + now_str \n",
        "! mkdir -p \"$drive_dir_path\"\n",
        "\n",
        "! echo ------------------------------------------\n",
        "! echo mannequinchallenge-vmd\n",
        "! echo ------------------------------------------\n",
        "    \n",
        "# 深度結果コピー\n",
        "depth_dir_path =  output_json + \"_\" + now_str + \"_depth\"\n",
        "\n",
        "! cd mannequinchallenge-vmd && python predict_video.py --video_path \"$input_video\" --json_path \"$output_json\" --past_depth_path \"$past_depth_dir_path\" --interval 20 --reverse_specific \"$reverse_specific\" --order_specific \"$order_specific\" --verbose 1 --now \"$now_str\" --avi_output \"yes\"  --number_people_max \"$number_people_max\" --end_frame_no \"$end_frame_no\" --input single_view --batchSize 1\n",
        "\n",
        "if os.path.exists( depth_dir_path + \"/error.txt\"):\n",
        "    \n",
        "    # エラー発生\n",
        "    ! cp \"$depth_dir_path\"/error.txt \"$drive_dir_path\"\n",
        "\n",
        "    ! echo \"■■■■■■■■■■■■■■■■■■■■■■■■\"\n",
        "    ! echo \"■■エラーが発生したため、処理を中断しました。\"\n",
        "    ! echo \"■■\"\n",
        "    ! echo \"■■■■■■■■■■■■■■■■■■■■■■■■\"\n",
        "\n",
        "    ! echo \"$drive_dir_path\" \"の error.txt の中身を確認してください。\"\n",
        "\n",
        "else:\n",
        "    \n",
        "    ! cp \"$depth_dir_path\"/*.avi \"$drive_dir_path\"\n",
        "    ! cp \"$depth_dir_path\"/message.log \"$drive_dir_path\"\n",
        "    ! cp \"$depth_dir_path\"/reverse_specific.txt \"$drive_dir_path\"\n",
        "    ! cp \"$depth_dir_path\"/order_specific.txt \"$drive_dir_path\"\n",
        "\n",
        "    # Googleドライブ再マウント\n",
        "    drive.mount('/gdrive')\n",
        "\n",
        "    elapsed_time = (time.time() - start_time) / 60\n",
        "\n",
        "    ! echo \"■■■■■■■■■■■■■■■■■■■■■■■■\"\n",
        "    ! echo \"■■【深度推定】の処理が終了しました\"\n",
        "    ! echo \"■■\"\n",
        "    ! echo \"■■処理にかかった時間：\" \"$elapsed_time\" \"分\"\n",
        "    ! echo \"■■■■■■■■■■■■■■■■■■■■■■■■\"\n",
        "\n",
        "    ! echo \"\"\n",
        "    ! echo \"MMD自動トレース実行結果\"\n",
        "\n",
        "    ! echo \"$drive_dir_path\"    \n",
        "    ! ls -l \"$drive_dir_path\"\n",
        "\n",
        "\n",
        "from IPython.display import Audio\n",
        "Audio(\"sceneswitch1.mp3\", autoplay=True)    "
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "Mm0tv4ykzsLn"
      },
      "source": [
        "### B) 自動トレース再実行(2D→3D）"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "MAGaxOsH0Daw",
        "cellView": "form"
      },
      "source": [
        "#@markdown ■■■■■■■■■■■■■■■■■■\n",
        "\n",
        "#@markdown 【セル⑨-B】　自動トレース再実行(2D→3D）\n",
        "\n",
        "#@markdown ■■■■■■■■■■■■■■■■■■\n",
        "\n",
        "#@markdown パラメーター設定のセルを実行したら、このセルを実行してください。\n",
        "\n",
        "#@markdown 人数分の処理が行われます。\n",
        "\n",
        "import time\n",
        "import datetime\n",
        "import cv2\n",
        "import os\n",
        "from google.colab import drive\n",
        "\n",
        "start_time = time.time()\n",
        "\n",
        "# Googleドライブマウント\n",
        "drive.mount('/gdrive')\n",
        "\n",
        "# 起点ディレクトリ\n",
        "drive_base_dir = \"/gdrive/My Drive/autotrace\"\n",
        "\n",
        "output_json = \"/content/output/json\"\n",
        "output_openpose_avi = \"/content/output/openpose.avi\"\n",
        "\n",
        "# 出力用Googleドライブフォルダ\n",
        "drive_dir_path = drive_base_dir + \"/\" + now_str \n",
        "! mkdir -p \"$drive_dir_path\"\n",
        "\n",
        "for i in range(1, number_people_max+1):\n",
        "    %tensorflow_version 1.x\n",
        "    \n",
        "    ! echo ------------------------------------------\n",
        "    ! echo 3d-pose-baseline-vmd [\"$i\"]\n",
        "    ! echo ------------------------------------------\n",
        "\n",
        "    target_name = \"_\" + now_str + \"_idx0\" + str(i)\n",
        "    target_dir = output_json + target_name\n",
        "\n",
        "    !cd ./3d-pose-baseline-vmd && python src/openpose_3dpose_sandbox_vmd.py --camera_frame --residual --batch_norm --dropout 0.5 --max_norm --evaluateActionWise --use_sh --epochs 200 --load 4874200 --gif_fps 30 --verbose 1 --openpose \"$target_dir\" --person_idx 1    \n",
        "\n",
        "    # INDEX別結果コピー\n",
        "    idx_dir_path = drive_dir_path + \"/idx0\" + str(i)\n",
        "    ! mkdir -p \"$idx_dir_path\"\n",
        "    ! cp \"$target_dir\"/pos.txt \"$idx_dir_path\"\n",
        "\n",
        "# Googleドライブ再マウント\n",
        "drive.mount('/gdrive')\n",
        "\n",
        "elapsed_time = (time.time() - start_time) / 60\n",
        "\n",
        "! echo \"■■■■■■■■■■■■■■■■■■■■■■■■\"\n",
        "! echo \"■■【2D→3D】の処理が終了しました\"\n",
        "! echo \"■■\"\n",
        "! echo \"■■処理にかかった時間：\" \"$elapsed_time\" \"分\"\n",
        "! echo \"■■■■■■■■■■■■■■■■■■■■■■■■\"\n",
        "\n",
        "! echo \"\"\n",
        "! echo \"MMD自動トレース実行結果\"\n",
        "\n",
        "! echo \"$drive_dir_path\"    \n",
        "! ls -l \"$drive_dir_path\"\n",
        "\n",
        "\n",
        "from IPython.display import Audio\n",
        "Audio(\"sceneswitch1.mp3\", autoplay=True)"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "tQh07oDkDCz0"
      },
      "source": [
        "### C) 自動トレース再実行(3D→VMD)"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "FULbLzXfyJ2W",
        "cellView": "form"
      },
      "source": [
        "#@markdown ■■■■■■■■■■■■■■■■■■\n",
        "\n",
        "#@markdown 【セル⑨-C】　自動トレース再実行(3D→VMD)\n",
        "\n",
        "#@markdown ■■■■■■■■■■■■■■■■■■\n",
        "\n",
        "#@markdown パラメーター設定のセルを実行したら、このセルを実行してください。\n",
        "\n",
        "#@markdown 人数分の処理が行われます。\n",
        "\n",
        "import time\n",
        "import datetime\n",
        "import cv2\n",
        "import shutil\n",
        "import glob\n",
        "from google.colab import drive\n",
        "\n",
        "start_time = time.time()\n",
        "\n",
        "# Googleドライブマウント\n",
        "drive.mount('/gdrive')\n",
        "\n",
        "# 起点ディレクトリ\n",
        "drive_base_dir = \"/gdrive/My Drive/autotrace\"\n",
        "\n",
        "output_json = \"/content/output/json\"\n",
        "output_openpose_avi = \"/content/output/openpose.avi\"\n",
        "\n",
        "# 出力用Googleドライブフォルダ\n",
        "drive_dir_path = drive_base_dir + \"/\" + now_str \n",
        "! mkdir -p \"$drive_dir_path\"\n",
        "\n",
        "\n",
        "for i in range(1, number_people_max+1):\n",
        "\n",
        "    ! echo ------------------------------------------\n",
        "    ! echo VMD-3d-pose-baseline-multi [\"$i\"]\n",
        "    ! echo ------------------------------------------\n",
        "    \n",
        "    target_name = \"_\" + now_str + \"_idx0\" + str(i)\n",
        "    target_dir = output_json + target_name\n",
        "\n",
        "    ! cd ./VMD-3d-pose-baseline-multi && python main.py -v 2 -t \"$target_dir\" -b \"$born_model_csv\" -c 30 -z \"$center_z_scale\" -s \"$smooth_times\" -p \"$threshold_pos\" -r \"$threshold_rot\" -k \"$is_ik\" -e \"$heel_position\" -d \"$depth_smooth_times\"\n",
        "\n",
        "    # INDEX別結果コピー\n",
        "    idx_dir_path = drive_dir_path + \"/idx0\" + str(i)\n",
        "    ! mkdir -p \"$idx_dir_path\"\n",
        "    ! cp \"$target_dir\"/*.vmd \"$idx_dir_path\"\n",
        "    # 日本語対策でpythonコピー\n",
        "    for f in glob.glob(target_dir +\"/*.vmd\"):\n",
        "        shutil.copy(f, idx_dir_path)\n",
        "\n",
        "# Googleドライブ再マウント\n",
        "drive.mount('/gdrive')\n",
        "\n",
        "elapsed_time = (time.time() - start_time) / 60\n",
        "\n",
        "! echo \"■■■■■■■■■■■■■■■■■■■■■■■■\"\n",
        "! echo \"■■【3D→VMD】の処理が終了しました\"\n",
        "! echo \"■■\"\n",
        "! echo \"■■処理にかかった時間：\" \"$elapsed_time\" \"分\"\n",
        "! echo \"■■■■■■■■■■■■■■■■■■■■■■■■\"\n",
        "\n",
        "! echo \"\"\n",
        "! echo \"MMD自動トレース実行結果\"\n",
        "\n",
        "! echo \"$drive_dir_path\"\n",
        "! ls -l \"$drive_dir_path\"\n",
        "\n",
        "\n",
        "from IPython.display import Audio\n",
        "Audio(\"sceneswitch1.mp3\", autoplay=True)"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "UzsQ7HrjphVF"
      },
      "source": [
        "# エラーが起きた場合"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "_JiZw2Ott1Rr"
      },
      "source": [
        "エラーが起きた場合、vmdファイルが生成されていない場合は、このセクションを上からひとつずつ実行してください。\n",
        "\n",
        "それでも解決しない場合、導入編の手順に従って、ノートブックのコピーを共有してください。"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "1uUbtOC7ptjz"
      },
      "source": [
        "## 1. Openposeが読み取る最初のフレームに、人数分映っていない場合"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "Mw8zNO_yG-Nt"
      },
      "source": [
        "error.txtに「最初のフレームに人数分のデータがありません。」と記載されている場合、Openposeが読み取る最初のフレームに人数分のデータがない事が原因です。\n",
        "\n",
        "下のセルを実行してください。"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "ppAVzFJzn4vh"
      },
      "source": [
        "!find output/json/ -name \"*.json\" | sort | head -n 1 | xargs ls -l\n",
        "!find output/json/ -name \"*.json\" | sort | head -n 1 | xargs cat"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "4e-MYAS-uLEx"
      },
      "source": [
        "【状況】\n",
        "下記のように、peopleの後ろにデータがない場合、0F目に人物データが取得できていません。\n",
        "\n",
        "![結果なし](https://drive.google.com/uc?export=view&id=1osssF0NCWply6J0-zPIhN2wm1gT0o6Io)\n",
        "\n",
        "【解決方法】\n",
        "\n",
        "人物が映っている最初のフレームを「【O】解析を開始するフレーム」に指定してください。\n",
        "\n",
        "「Openposeが読み取ったフレームリスト30件」のセルを実行すると、先頭30件のOpenpose結果ファイルが表示されます。\n",
        "\n",
        "![先頭30件](https://drive.google.com/uc?export=view&id=1lxP78w4NIbQSKWhpfbynCjDKOgmcNp0o)\n",
        "\n",
        "人物データがないJSONファイルは、ファイルサイズがとても小さいです。（図の場合、0F目が人物データなし）\n",
        "\n",
        "1人分のデータで大体500Byte前後(0.5KB)のファイルサイズになります。\n",
        "\n",
        "これを参考にして、先頭のフレーム番号を決めてください。元動画の編集や再アップロードは不要です。\n",
        "\n",
        "先頭のフレーム番号が決まったら、「パラメーター設定」セクションの「【O】解析を開始するフレーム」に、その番号を入力して、「パラメーター設定」＞「自動トレース実行（全実行）」の順で実行してください。\n",
        "\n",
        "\n",
        "複数人トレースの場合は、0F目（【O】解析を開始するフレーム）には全員映っている必要があります。\n",
        "ファイルサイズも人数分増えますので、目安にしてください。"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "cYIc5neP9oAl"
      },
      "source": [
        "## 2. Openposeが読み取ったフレームリスト先頭30件"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "qT0qOAp09xlM"
      },
      "source": [
        "ls -l output/json/*.json | head -n 30"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "NCckdf_gp0F2"
      },
      "source": [
        "## 3. Googleドライブにファイルが追加されない場合"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "wWIauqkWq15H"
      },
      "source": [
        "error.txt もvmdも何も出力されなかった場合、セルの出力結果を確認してください。\n",
        "\n",
        "最後にファイル名のリストが出ている場合、出力自体は成功しています。\n",
        "\n",
        "ただ、Googleドライブとの連携が済んでいるにも関わらず、データが反映されないケースを確認しています。\n",
        "\n",
        "詳細は調査中ですが、とりあえずの対応として、クラウド上の元データをダウンロードしてください。\n",
        "\n",
        "1. 目次の横にある「ファイル」欄をクリックする\n",
        "2. ヘッダの「更新」をクリックする\n",
        "3. output ＞ json を開く\n",
        "4. xxx_depth ＞ output_XXX.avi …　背景AVI(MMD)\n",
        "5. xxx_idxXX ＞ output_XXX.vmd　…　モーションデータ(MMD)\n",
        "6. xxx_idxXX ＞ pos.txt　…　3D関節位置データ(Unity)\n",
        "7. 複数人数のトレースした場合、idxが複数件できています。\n",
        "\n",
        "![クラウドデータ](https://drive.google.com/uc?export=view&id=1fArRyRdfs1kBLaLTpdkdJ-MYwHNe-UUq)\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "ASco7yEigfFn"
      },
      "source": [
        "## 4. すべてやり直したい場合"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "X0leFRGtgoP7"
      },
      "source": [
        "準備がうまくいかなかった場合などで、全部やり直したい場合、ランタイムをリセットしてください。\n",
        "\n",
        "ヘッダ　＞　「ランタイム」　＞　「すべてのランタイムをリセット」\n",
        "\n",
        "![リセット](https://drive.google.com/uc?export=view&id=1AYX8hv5mmAsbhF8o0S3_6hhdNeax9c8J)\n",
        "\n",
        "確認ダイアログが出ますので、OKして進めてください。"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "iOLiarVDw_TY"
      },
      "source": [
        "# TIPS"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "oiVbKfOVxByH"
      },
      "source": [
        "上記の他、思いつくままに、参考になりそうな事を。"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "RS2M0r4vFH5Z"
      },
      "source": [
        "## オススメの作業順番"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "ESNt5KETxMqv"
      },
      "source": [
        "\n",
        "私は以下の順番で作業を行っています。\n",
        "\n",
        "1. **「【O】映像に映っている最大人数」**に、トレース元動画からトレースしたい人数を入力して、セルを実行する\n",
        "2. **「自動トレース実行（全実行）」**のセルを実行する\n",
        "3. 結果がエラーになった場合、「エラーが起きた場合」の**「Openposeが読み取る最初のフレームに、人数分映っているか」**を実行して、人物が映っているフレームを確認する。成功していたら6に移動。\n",
        "4. **「【O】解析を開始するフレーム」**に、3で見つけたフレーム番号を入力する\n",
        "5. **「パラメーター設定」**のセルを実行する\n",
        "6. **「A) 自動トレース再実行(深度推定)」**のセルを実行する\n",
        "7.   複数人数のトレースで、入れ替わりが認識できていない場合、message.logを見ながら、**「【F】順番指定リスト」**に順番を指定する\n",
        "8. **「パラメーター設定」**のセルを実行する\n",
        "9. **A) 自動トレース再実行(深度推定)」**のセルを実行する\n",
        "10. 入れ替わりの順番指定が納得いくまで、7～9を繰り返す\n",
        "11. 意図しない回転があった場合、message.logを見ながら、**「【F】反転指定リスト」**に該当フレームの正しい反転状況を指定して設定する　\n",
        "  - ※副薄人数トレースで並び順番が変わると、反転指定の人物INDEXも変わるため、順番指定が終わった後に実行した方がよい。\n",
        "12. **「パラメーター設定」**のセルを実行する\n",
        "13. **A) 自動トレース再実行(深度推定)」**のセルを実行する\n",
        "14. 納得いくまで、11～13を繰り返す\n",
        "15. 入れ替えや回転の指定が完了したら、**「B) 自動トレース再実行(2D→3D）」**を実行する\n",
        "16. **「パラメーター設定」**の【V】の値を調整する\n",
        "17. **「パラメーター設定」**のセルを実行する\n",
        "18. **「C) 自動トレース再実行(3D→VMD)」**のセルを実行する。複数人数のトレースの場合も１回で人数分出力されます。\n",
        "19. 納得いくまで、15～18を繰り返す\n",
        "\n",
        "頑張って下さい！"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "AhrZcOhMxO2f"
      },
      "source": [
        "## トレースしやすい動画"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "assKjr_XxRKL"
      },
      "source": [
        " - 固定カメラである\n",
        " - 関節がはっきり分かる\n",
        "    - ロングスカートや和服等、関節が見えにくい人体は苦手です\n",
        "    - 背景が人物と似た色である、影が濃く映っている、などの場合、トレースを間違える事が多いです\n",
        "    - 手首・足首まで映っている方が、精度が高くなります\n",
        "    - 真っ黒なズボン等で、左右の区別がつきにくい場合、精度が落ちます\n",
        " - 最初のフレームで前向きである\n",
        "   - 後ろや横を向いていると始めのデータが綺麗に取れません（一度正面を向いてくれると直る事が多いです）\n",
        " - 最初のフレームで全身の関節が判別できる\n",
        "   - どこか隠れていると、それだけ精度が落ちます\n",
        " - 頭が上、足が下\n",
        "   - 逆立ちやキックなどで高く足が上がっている場合、足を手と誤認識します。（特に首より足の根元の関節が上になっている場合など）\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "umaYNzP34XKU"
      },
      "source": [
        "## 課題"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "SpqJj6mY4ahj"
      },
      "source": [
        " - 回転が取れていない関節\n",
        "   - 手首\n",
        "   - 指\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "r9CQDK0a1IaH"
      },
      "source": [
        "# ライセンス"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "AfTobZSD1KHy"
      },
      "source": [
        "MMD自動トレースの結果を公開・配布する場合は、必ずライセンスのご確認をお願い致します。Unityの場合も同様です。\n",
        "\n",
        "ライセンスを記載いただけたらとても有難いです。\n",
        "\n",
        "[MMDモーショントレース自動化キットライセンス](https://ch.nicovideo.jp/miu200521358/blomaga/ar1686913)"
      ]
    }
  ]
}